﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Security.Cryptography;
using System.Text;


namespace FinlogiK.FxCop.Statistics.Windows.Properties
{
	internal sealed partial class Settings
	{
		#region Fields

		private readonly byte[] _encryptionEntropy = new byte[] { 50, 191, 238, 206, 128, 65, 109, 190, 165, 192, 13, 199, 177, 141, 87, 252, 7, 1, 30, 44, 121, 21, 104, 8, 92, 121, 248, 88, 112, 109, 161, 19, 175, 161, 71, 127, 223, 169, 138, 18, 47, 174, 43, 90, 245, 243, 49, 48, 157, 149, 204, 129, 68, 99, 7, 7, 250, 213, 54, 163, 73, 143, 234, 64, 83, 189, 79, 169, 45, 178, 160, 215, 73, 153, 157, 217, 24, 169, 75, 254, 36, 51, 205, 93, 110, 176, 59, 41, 195, 63, 188, 13, 200, 197, 142, 27, 94, 55, 74, 61, 191, 231, 173, 144, 239, 45, 6, 88, 91, 24, 33, 192, 82, 21, 47, 79, 176, 5, 31, 6, 100, 212, 181, 8, 137, 147, 177, 235 };

		private event ValueChangedEventHandler<bool> _databaseConfigurationCompleteChanged;

		#endregion

		#region Constructors

		internal Settings()
		{
		}

		#endregion

		#region Properties

		private byte[] EncryptionEntropy
		{
			get
			{
				return this._encryptionEntropy;
			}
		}

		internal bool IsDatabaseConfigurationComplete
		{
			get
			{
				return !string.IsNullOrEmpty(this.StatisticsDatabase);
			}
		}

		internal string FxCopStatisticsConnectionString
		{
			get
			{
				return this.StatisticsDatabase;
			}
		}

		internal event ValueChangedEventHandler<bool> DatabaseConfigurationCompleteChanged
		{
			add
			{
				this._databaseConfigurationCompleteChanged += value;
			}
			remove
			{
				this._databaseConfigurationCompleteChanged -= value;
			}
		}

		#endregion

		#region Methods

		protected override void OnSettingsLoaded(object sender, SettingsLoadedEventArgs e)
		{
			this.StatisticsDatabase = this.Decrypt(this.StatisticsDatabase).Trim();
			base.OnSettingsLoaded(sender, e);
		}

		public override void Save()
		{
			string connectionString = this.StatisticsDatabase.Trim();
			this.StatisticsDatabase = this.Encrypt(connectionString);		
			try
			{
				base.Save();
			}
			finally
			{
				this.StatisticsDatabase = connectionString;
			}

			if(this._databaseConfigurationCompleteChanged != null)
			{
				this._databaseConfigurationCompleteChanged(this, new ValueChangedEventArgs<bool>(this.IsDatabaseConfigurationComplete));
			}
		}

		private string Encrypt(string value)
		{
			string result = string.Empty;

			if (!string.IsNullOrEmpty(value))
			{
				byte[] data = Encoding.Unicode.GetBytes(value);
				data = ProtectedData.Protect(data, this.EncryptionEntropy, DataProtectionScope.CurrentUser);
				result = Convert.ToBase64String(data);
			}

			return result;
		}

		private string Decrypt(string value)
		{
			string result = string.Empty;

			if (!string.IsNullOrEmpty(value))
			{
				byte[] data = Convert.FromBase64String(value);
				data = ProtectedData.Unprotect(data, this.EncryptionEntropy, DataProtectionScope.CurrentUser);
				result = Encoding.Unicode.GetString(data);
			}

			return result;
		}

		#endregion
	}
}